package lrc2video.happy.lyrics;

import lrc2video.happy.lyrics.model.LyricsInfo;
import lrc2video.happy.lyrics.model.LyricsLineInfo;
import lrc2video.happy.lyrics.model.LyricsTag;
import org.apache.commons.codec.binary.Base64;

import java.io.*;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.TreeMap;

/**
 * @Description: 歌词文件读取器
 * @Author: zhangliangming
 * @Date: 2017/12/25 16:08
 * @Version:
 */
public abstract class LyricsFileReader {
    /**
     * 默认编码
     */
    private Charset defaultCharset = Charset.forName("utf-8");

    /**
     * 读取歌词文件
     *
     * @param file
     * @param mp3TimeLength
     * @return
     */
    public LyricsInfo readFile(File file, double mp3TimeLength) throws Exception {
        if (file != null) {
            return readInputStream(new FileInputStream(file), mp3TimeLength);
        }
        return null;
    }

    /**
     * 读取歌词文本内容
     *
     * @param base64FileContentString base64位文件内容
     * @param saveLrcFile             要保存的歌词文件
     * @return
     * @throws Exception
     */
    public LyricsInfo readLrcText(String base64FileContentString,
                                  File saveLrcFile, double mp3TimeLength) throws Exception {
        byte[] fileContent = Base64.decodeBase64(base64FileContentString);

        if (saveLrcFile != null) {
            // 生成歌词文件
            FileOutputStream os = new FileOutputStream(saveLrcFile);
            os.write(fileContent);
            os.close();

            os = null;
        }

        return readInputStream(new ByteArrayInputStream(fileContent), mp3TimeLength);
    }

    /**
     * 读取歌词文本内容
     *
     * @param base64ByteArray base64内容数组
     * @param saveLrcFile
     * @return
     * @throws Exception
     */
    public LyricsInfo readLrcText(byte[] base64ByteArray, File saveLrcFile, double mp3TimeLength)
            throws Exception {
        if (saveLrcFile != null) {
            // 生成歌词文件
            FileOutputStream os = new FileOutputStream(saveLrcFile);
            os.write(base64ByteArray);
            os.close();

            os = null;
        }

        return readInputStream(new ByteArrayInputStream(base64ByteArray), mp3TimeLength);
    }

    /**
     * @param dynamicContent  动感歌词内容
     * @param lrcContent      lrc歌词内容
     * @param extraLrcContent 额外歌词内容（翻译歌词、音译歌词）
     * @param lyricsFilePath  歌词文件保存路径
     * @return
     * @throws Exception
     */
    public abstract LyricsInfo readLrcText(String dynamicContent,
                                           String lrcContent, String extraLrcContent, String lyricsFilePath)
            throws Exception;

    /**
     * 读取歌词文件
     *
     * @param in
     * @param mp3TimeLength
     * @return
     */
    public abstract LyricsInfo readInputStream(InputStream in, double mp3TimeLength) throws Exception;

    /**
     * 支持文件格式
     *
     * @param ext 文件后缀名
     * @return
     */
    public abstract boolean isFileSupported(String ext);

    /**
     * 获取支持的文件后缀名
     *
     * @return
     */
    public abstract String getSupportFileExt();

    public void setDefaultCharset(Charset charset) {
        defaultCharset = charset;
    }

    public Charset getDefaultCharset() {
        return defaultCharset;
    }

    /**
     * 判断文件的编码格式
     *
     * @param file
     * @return
     */
    public String getCharsetName(File file) {
        String code = "UTF-8";
        BufferedInputStream bin = null;
        try {
            bin = new BufferedInputStream(new FileInputStream(file));
            int p = (bin.read() << 8) + bin.read();

            switch (p) {
                case 0xefbb:
                    code = "UTF-8";
                    break;
                case 0xfffe:
                    code = "Unicode";
                    break;
                case 0xfeff:
                    code = "UTF-16BE";
                    break;
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bin != null) {
                try {
                    bin.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return code;
    }

    /**
     * 存在开始时间是小于0的，如果时间小于0那么就全部设置为0<br/>
     * 如果处理的歌词时长大于音频时长就全部修改音频时长<br/>
     * 并且模拟一个偏移时间
     */
    public static void againInitOffSet(LyricsInfo lyricsIfno) {
        TreeMap<Integer, LyricsLineInfo> lyricsLineInfoTreeMap = lyricsIfno.getLyricsLineInfoTreeMap();
        double mp3TimeLengthms = lyricsIfno.getTimeLength() * 1000;
        for (Integer integer : lyricsLineInfoTreeMap.keySet()) {
            LyricsLineInfo lyricsLineInfo = lyricsLineInfoTreeMap.get(integer);
            if (lyricsLineInfo.getStartTime() < 0) {
                lyricsLineInfo.setStartTime(0);
            }
            if (lyricsLineInfo.getEndTime() < lyricsLineInfo.getStartTime()) {
                lyricsLineInfo.setEndTime(lyricsLineInfo.getStartTime());
            }
            // 处理所有的开始时间和结束时间 不能大于音频时间长度一秒
            if (lyricsLineInfo.getStartTime() - mp3TimeLengthms > 1000) {
                lyricsLineInfo.setStartTime((int) (mp3TimeLengthms));
            }
            if (lyricsLineInfo.getEndTime() - mp3TimeLengthms > 1000) {
                lyricsLineInfo.setEndTime((int) (mp3TimeLengthms));
            }
        }
        // 没有偏移时间，模拟一个
        boolean b = lyricsIfno.getLyricsTags().containsKey(LyricsTag.TAG_OFFSET);
        if (!b) {
            lyricsIfno.getLyricsTags().put(LyricsTag.TAG_OFFSET, String.valueOf(lyricsLineInfoTreeMap.get(0).getStartTime()));
        }
    }
}
